﻿#region Header

/***************************************************************************
Author : Krishan Kaliraman (www.sharedwith.me)  Date: 1 Aug 2012
***************************************************************************/

#endregion Header

using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Mail;
using System.Text;
using System.Configuration;
using System.Collections.Generic;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Server;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Data.SqlClient;
using System.Data;
using System;

namespace Common
{
    using System;

    public static class Helper
    {
        #region Methods

        public static Uri GetCollectionUri(string[] args)
        {
            String collectionUri;
            
            if ((args.Length > 0) && (!String.IsNullOrEmpty(args[0])) && 
                Uri.IsWellFormedUriString(args[0], UriKind.Absolute))
            {
                collectionUri = args[0];               
            }
            else
            {
                collectionUri = Environment.GetEnvironmentVariable("TFS_COLLECTION_URI");
            }

            while (String.IsNullOrEmpty(collectionUri))
            {
                //Console.WriteLine(
                //    "Please enter your TFS Team Project Collection URI,\n" +
                //    "or you can set it in TFS_COLLECTION_URI environment variable:");

                //collectionUri = Console.ReadLine();
                collectionUri =StaticItems.TfsUrl;

                if (!Uri.IsWellFormedUriString(collectionUri, UriKind.Absolute))
                {
                    collectionUri = null;
                }
            }

            return new Uri(collectionUri);
        }

        public static Identity[] LoadTFSUsersandPrintThemOnPage()
        {
            Identity[] UserId;
            using (var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(GetCollectionUri(new string[] { })))
            {
                // get a reference to the work item tracking service
                IGroupSecurityService gss = projectCollection.GetService<IGroupSecurityService>();
                Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "Project Collection Valid Users", QueryMembership.Expanded);

                 UserId = gss.ReadIdentities(SearchFactor.Sid, SIDS.Members, QueryMembership.None);

                //foreach (Identity user in UserId)
                //{
                //    Console.WriteLine(user.AccountName);
                //    Console.WriteLine(user.DisplayName);
                //}
                
            }
            return UserId;

        }

        internal static bool AuthenticateTfsUser(NetworkCredential networkCredential)
        {
            bool IsTfsUserAuthenticated = false;
            var collectionUri = GetCollectionUri(new string[] { });
            TfsConfigurationServer ConfigurationServer = new TfsConfigurationServer(collectionUri, networkCredential);
            try
            {
                ConfigurationServer.Authenticate();
                IsTfsUserAuthenticated = true;
            }
            catch(Exception ex)
            {
                IsTfsUserAuthenticated = false;
                Console.Write(ex.Message);
            }
            return IsTfsUserAuthenticated;
        }

        internal static Identity[] LoadTFSUsers(NetworkCredential networkCredentials)
        {
            Identity[] UserId = null;
            var collectionUri = GetCollectionUri(new string[] { });
            TfsConfigurationServer ConfigurationServer = new TfsConfigurationServer(collectionUri, networkCredentials);
            ConfigurationServer.Authenticate();
            ReadOnlyCollection<CatalogNode> collectionNodes = ConfigurationServer.CatalogNode.QueryChildren(
               new[] { CatalogResourceTypes.ProjectCollection },
               false, CatalogQueryOptions.None);
            WorkItemCollection workItems = null;
            foreach (CatalogNode collectionNode in collectionNodes)
            {
                Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
                TfsTeamProjectCollection teamProjectCollection = ConfigurationServer.GetTeamProjectCollection(collectionId);
                if (teamProjectCollection.Name == "Advantage")
                {
                    try
                    {
                        IGroupSecurityService gss = teamProjectCollection.GetService<IGroupSecurityService>();
                        Identity SIDS = gss.ReadIdentity(SearchFactor.AccountName, "Project Collection Valid Users", QueryMembership.Expanded);

                        UserId = gss.ReadIdentities(SearchFactor.Sid, SIDS.Members, QueryMembership.None);
                        break;
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("Error: {0}", e.Message);
                    }
                }
            }
            return UserId;
        }
        
        public static WorkItemCollection GetWorkItems(string wiqlQuery)
        {
            // get the Uri to the project collection to use
            var collectionUri = GetCollectionUri(new string[] { });
            WorkItemCollection workItems = null;
            try
            {

                // get a reference to the team project collection
                using (var projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(collectionUri))
                {
                    // get a reference to the work item tracking service
                    var workItemStore = projectCollection.GetService<WorkItemStore>();
                    workItems = workItemStore.Query(wiqlQuery);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.Message);
            }
            return workItems;
        }
        
        public static WorkItemCollection GetWorkItems(string wiqlQuery , NetworkCredential userCredentials)
        {
            var collectionUri = GetCollectionUri(new string[] { });
            TfsConfigurationServer ConfigurationServer = new TfsConfigurationServer(collectionUri, userCredentials);
            ConfigurationServer.Authenticate();
            ReadOnlyCollection<CatalogNode> collectionNodes = ConfigurationServer.CatalogNode.QueryChildren(
               new[] { CatalogResourceTypes.ProjectCollection },
               false, CatalogQueryOptions.None);
            WorkItemCollection workItems = null;
            foreach (CatalogNode collectionNode in collectionNodes)
            {
                Guid collectionId = new Guid(collectionNode.Resource.Properties["InstanceId"]);
                TfsTeamProjectCollection teamProjectCollection =ConfigurationServer.GetTeamProjectCollection(collectionId);
                //if (teamProjectCollection.Name == "Advantage")
                //{
                //    try
                //    {
                        var workItemStore = teamProjectCollection.GetService<WorkItemStore>();
                        workItems = workItemStore.Query(wiqlQuery);
                        break;
                //    }
                    //catch (Exception e)
                    //{
                    //    Console.WriteLine("Error: {0}", e.Message);
                    //}
                //}
            }
            return workItems;
        }
        #endregion Methods

        public static void SendStatusEmail(List<TeamMember> allTeamMembersCollection, NameValueCollection allTeamMembers, List<Activity> allCommittedWorkItemsForSprintWithTheirTasksLists , QuoteOfTheDay quoteOfTheDay=null)
        {
            string userName = "Team ,";
            StringBuilder mailBody = new StringBuilder();
            mailBody.AppendFormat("Dear {0}", userName);
            mailBody.AppendFormat("<br />");
            mailBody.AppendFormat("<p>This is automated status email for last 24 hours tfs updates.</p><p>*     means team member was too busy to update the tfs or is on leave.</p>");
            if (!string.IsNullOrEmpty(ConfigurationManager.AppSettings["SendQuote"]) && ConfigurationManager.AppSettings["SendQuote"].ToUpper() == "TRUE")
            {
                if (quoteOfTheDay != null)
                {
                    mailBody.AppendFormat("<p> <b> Quote Of The Day : </b> <i>" + quoteOfTheDay.Quote + " - " + quoteOfTheDay.Author +
                                          "</i></p>");
                }
            }

            mailBody.AppendFormat("<p>");
            mailBody.AppendFormat("<a  href=\"" + ConfigurationManager.AppSettings["SprintChartUrl"] + "?team=" + ConfigurationManager.AppSettings["NodeName"] +
                                        "\" style=\"font-family:Arial;font-size:9pt;\">Click Me</a>" + " to see <i> <b>" + StaticItems.CurrentSprintIteration + "</b></i> in graphical representation.");
            if(StaticItems.TeamDocuments.Count>0)
            {
                foreach (string currentKey in StaticItems.TeamDocuments.AllKeys)
                {
                    mailBody.AppendFormat("<a  href=\"" +StaticItems.TeamDocuments[currentKey] +
                                 "\" style=\"font-family:Arial;font-size:9pt;\">Click Me</a>" + " to see " + currentKey + ". ");
                }
            }
            mailBody.AppendFormat("</p>");
            string status = GetStatus(allTeamMembersCollection, allTeamMembers, allCommittedWorkItemsForSprintWithTheirTasksLists);
            mailBody.Append(status);
            MailMessage message = new MailMessage();
            AddAllEmailAddressIntoToListOfMessage(message, StaticItems.RecepientTo);
            message.Subject = GetSubject();
            message.IsBodyHtml = true;

            message.Body = mailBody.ToString();
            
            //message.From = new MailAddress("BE-Shiva-India-Gurgaon@jci.com");
            message.From = new MailAddress(StaticItems.From);
            string messageCc = ConfigurationManager.AppSettings["cc"];
            if (!string.IsNullOrEmpty(messageCc))
            {
                message.CC.Add(new MailAddress(messageCc));
            }
            SmtpClient smtpServer = new SmtpClient("mhub.corp.jci.com");
            
            //smtpServer.Credentials = new System.Net.NetworkCredential(ConfigurationManager.AppSettings["username"], ConfigurationManager.AppSettings["password"]);
            smtpServer.EnableSsl = false;

            smtpServer.Send(message);
            Console.WriteLine("Email Sent");
        }
        private static void AddAllEmailAddressIntoToListOfMessage(MailMessage message, string toList)
        {
            string[] emailToAddressList = toList.Split(new char[] { ',' });
            foreach (var currentEmailAddress in emailToAddressList)
            {
                message.To.Add(new MailAddress(currentEmailAddress));
            }
        }

        private static string GetStatus(List<TeamMember> allTeamMembersCollection, NameValueCollection allTeamMembers,List<Activity> allCommittedWorkItemsForSprintWithTheirTasksLists)
        {
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("<table>");
            sb.AppendFormat("<tr><td><b><i>Member</i></b></td><td><b><i>PBI Id </i></b></td><td><b><i>Task Id </i></b></td><td><b><i>Title</i></b></td> <td><b><i>Task Type</i></b></td> <td><b><i>State</i></b></td></tr>");
            string[] randTeamMembersSource = new string[allTeamMembers.Keys.Count];
            string[] randTeamMembersFinal = new string[allTeamMembers.Keys.Count];
            int count = 0;
            foreach(string currentTeamMember in allTeamMembers.Keys)
            {
                randTeamMembersSource[count] = currentTeamMember;
                count = count + 1;
            }
            Random rnd = new Random();
            int indexStr = rnd.Next(0, randTeamMembersSource.Count());
            count = 0;
            foreach (var item in randTeamMembersSource.OrderBy(R => Guid.NewGuid()).Distinct().Take(allTeamMembers.Keys.Count))
            {
                randTeamMembersFinal[count] = item;
                count = count + 1;
            }
            foreach (string currentTeamMember in randTeamMembersFinal)
            {
                foreach (var teamMember in allTeamMembersCollection)
                {
                    if (teamMember.MemberName == currentTeamMember)
                    {
                        int activityCounter = 0;
                        
                        foreach (var currentCommittedWorkItem in allCommittedWorkItemsForSprintWithTheirTasksLists)
                        {
                            int parentActivityCounter = 0;
                            List<Activity> temMemberActivitesPertainingToCurrentCommittedWorkItem = new List<Activity>();
                            foreach (var activity in teamMember.TemMemberActivities)
                            {
                                temMemberActivitesPertainingToCurrentCommittedWorkItem.AddRange(from currentLinkedWorkItemId in currentCommittedWorkItem.IdOfAlllinkedWorkItems where activity.Id == currentLinkedWorkItemId select activity);
                            }
                            foreach (var currentActivity in temMemberActivitesPertainingToCurrentCommittedWorkItem)
                            {
                                sb.AppendFormat("<tr>");
                                if (activityCounter == 0)
                                {
                                    sb.AppendFormat("<td title=\"" + teamMember.MemberRemainingWorkItems.Replace("\"", "'") + "\"><i>" + teamMember.MemberDisplayName + "</i></td>");
                                }
                                else
                                {
                                    sb.AppendFormat("<td></td>");
                                }
                                if (parentActivityCounter==0)
                                {
                                    sb.AppendFormat("<td title=\"" + currentCommittedWorkItem.Title.Replace("\"", "'") + "\">" + currentCommittedWorkItem.Id + "</td>");
                                }
                                else
                                {
                                    sb.AppendFormat("<td></td>");
                                }
                                if (string.IsNullOrEmpty(currentActivity.ActivityType))
                                {
                                    sb.AppendFormat("<td>" + currentActivity.Id + "</td> <td>" + currentActivity.Title +"</td>" + "<td>" + ":)" + "</td>" + "<td>" +currentActivity.State + "</td>");
                                }
                                else
                                {
                                    sb.AppendFormat("<td>" + currentActivity.Id + "</td> <td>" + currentActivity.Title +"</td>" + "<td>" + currentActivity.ActivityType + "</td>" + "<td>" +currentActivity.State + "</td>");
                                }
                                sb.AppendFormat("</tr>");
                                activityCounter = activityCounter + 1;
                                parentActivityCounter = parentActivityCounter + 1;
                            }
                            if (teamMember.TemMemberActivities.Count == 0)
                            {
                                sb.AppendFormat("<tr>");
                                sb.AppendFormat("<td title=\"" + teamMember.MemberRemainingWorkItems.Replace("\"", "'") + "\"><i>" + teamMember.MemberDisplayName + "</i></td>");
                                sb.AppendFormat("<td> * </td> <td> * </td> <td> * </td> <td>*</td> <td>*</td>");
                                sb.AppendFormat("</tr>");
                                break;
                            }
                           
                        }
                    }
                    sb.AppendFormat("<tr><td></td><td></td><td></td><td></td></tr>");
                }
            }
            sb.AppendFormat("</table>");
            string regards = "<p>Regards,</p><p>Team " + ConfigurationManager.AppSettings["NodeName"] + "</p>";
            sb.AppendFormat(regards);
            return sb.ToString();
        }

        private static string GetSubject()
        {
            return  DateTime.Today.Day.ToString() + "-" + DateTime.Today.Month.ToString() + "-" + DateTime.Today.Year + "  Daily Status email!";
        }

        public static bool CheckForAssignMenetToTeamMember(NameValueCollection allTeamMembers, string currentItemAssignedTo)
        {
            bool ismemberInTeam = allTeamMembers.Keys.Cast<object>().Any(currentMember => currentMember.ToString() == currentItemAssignedTo);
            return ismemberInTeam;
        }

        public static bool CheckForTodaydate(string passedDate)
        {
            DateTime datePassed = Convert.ToDateTime(passedDate);
            DateTime now = DateTime.Parse(DateTime.Now.ToString(), null, DateTimeStyles.AdjustToUniversal);
            DateTime nowMinusTwentyFourHours = now.AddHours(-24);
            if (datePassed <= now && datePassed > nowMinusTwentyFourHours)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public static void FillTeamMembersAndActivities(List<Activity> todayUpdatedWorkItems, NameValueCollection allMembersInTeam)
        {
            foreach (var currentTeamMember in allMembersInTeam.Keys)
            {
                var newTeamMember = new TeamMember(todayUpdatedWorkItems, currentTeamMember.ToString(), allMembersInTeam[currentTeamMember.ToString()]);
                StaticItems.AllTeamMembersCollection.Add(newTeamMember);
            }
        }

        public static void FilterWorkItemsForAllTeamMembers(List<Activity> workItemsUpdatedForToday, List<Activity> totalWorkItemsInPipeLineForCurrentSprint, WorkItemCollection workItems)
        {
            foreach (WorkItem workItem in workItems)
            {
                string currentWorkItemType = workItem[workItem.Fields["System.WorkItemType"].Name].ToString();
                string currentWorkItemIterationPath = workItem[workItem.Fields["System.IterationPath"].Name].ToString();
                Activity newActivity = null;
                string currentItemAssignedTo = workItem[workItem.Fields["System.AssignedTo"].Name].ToString();
                string currentItemChangedDate = workItem[workItem.Fields["System.ChangedDate"].Name].ToString();
                string currentItemState = workItem[workItem.Fields["System.State"].Name].ToString();
                bool currentdateFlag = CheckForTodaydate(currentItemChangedDate);
                bool isAssignedToTeamTeamMember = CheckForAssignMenetToTeamMember(StaticItems.allTeamMembers, currentItemAssignedTo);
                if (isAssignedToTeamTeamMember && currentdateFlag)
                {
                    newActivity = new Activity(workItem);
                    workItemsUpdatedForToday.Add(newActivity);
                }
                if (isAssignedToTeamTeamMember && (currentItemState == "To Do" || currentItemState == "In Progress"))
                {
                    newActivity = new Activity(workItem);
                    totalWorkItemsInPipeLineForCurrentSprint.Add(newActivity);
                }
            }
        }

        public static bool IsWorkItemInProgressOrToDo(WorkItem workItem)
        {
            string state = workItem[workItem.Fields["System.State"].Name].ToString();
            bool isWorkItemInProgressOrToDo = false;
            if(state=="In Progress" || state=="To Do" || state =="Done")
            {
                isWorkItemInProgressOrToDo = true;
            }
            return isWorkItemInProgressOrToDo;
        }

        internal static DataTable GetDataTable(string sqlQuery)
        {
            DataTable dataTable=new DataTable ();
            string connectionString = ConfigurationManager.AppSettings["ActivityDataBaseConnection"];
            using (SqlConnection connection =
                       new SqlConnection(connectionString))
            {
                SqlCommand command = connection.CreateCommand();
                command.CommandText = sqlQuery ;
                SqlDataAdapter ada = new SqlDataAdapter();
                try
                {
                    ada.SelectCommand = command;
                    ada.Fill(dataTable);
                
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            return dataTable;
        }

        internal static void ExecuteSqlStatement(string sqlQuery)
        {
            string connectionString = ConfigurationManager.AppSettings["ActivityDataBaseConnection"];
            SqlConnection connection = new SqlConnection(connectionString);
            connection.Open();
            using (connection)
            {
                SqlCommand command = connection.CreateCommand();
                command.CommandText = sqlQuery;
                try
                {
                    command.ExecuteNonQuery();

                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
    }
}